from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from django.views import View
from django.http import JsonResponse
from django.contrib import auth
from django.core.cache import cache
from django.conf import settings
from django.contrib.auth.decorators import login_required
from utlis import forms
from utlis.Image_code import AuthCode
from libs.tx_sms import send_sms
from user import models
from common.send_email import send_email
from common.send_email import get_token_obj
from common.logger import log
from io import BytesIO
import re


class RegisterView(View):
    '''注册功能'''

    def get(self, request):
        form_obj = forms.RegForm()
        return render(request, 'user/register.html',
                      {'form_obj': form_obj})

    def post(self, request):
        '''
        注册后，发送激活邮件
        '''
        form_obj = forms.RegForm(request.POST)
        back_dic = {'code': 1000, 'msg': ''}

        # 判断校验是否通过
        if form_obj.is_valid():
            '''
            需要校验激活用户和未激活用户是否存在
            '''


            # 校验激活用户是否存在
            username = form_obj.cleaned_data.get('username')
            email = form_obj.cleaned_data.get('email')
            # 客户端发送的HTTP HOST头，即请求的服务器ip
            host = request.get_host()

            user_obj = models.User.objects.filter(username= username,
                                                  is_active= True).first()
            if user_obj:
                form_obj.add_error('username', '用户已存在')
                back_dic['code'] = 1001
                back_dic['msg'] = form_obj.errors

            # 校验未激活态用户是否存在
            user_again_obj = models.User.objects.filter(username= username,
                                                        is_active= False).first()
            if not user_again_obj:
                # 用户不存在则创建用户,并发送激活邮件
                clean_data = form_obj.cleaned_data
                clean_data.pop('confirm_password')
                # 判断头像是否为空

                avatar_obj = request.FILES.get('avatar')
                if avatar_obj:
                    clean_data['avatar'] = avatar_obj
                user = models.User.objects.create_user(**clean_data)

                # 发送激活邮件
                send_email.delay(user.username, host, email)
                back_dic['url'] = '/user/message/'
                log.info(f'{username}用户已注册，尚未激活')
                # return render(request, 'user/email_active/regmessage.html')

            else:
                # 用户存在，则发送激活邮件
                send_email.delay(username, host, email)

                form_obj.add_error('username',
                                   '用户已注册未激活，请及时登录到注册邮箱激活用户')
                back_dic['code'] = 1002
                back_dic['msg'] = form_obj.errors

        else:
            back_dic['code'] = 1003
            back_dic['msg'] = form_obj.errors

        return JsonResponse(back_dic)


def message(request):
    '''# 注册用户后，返回激活提示页面'''
    return render(request,
                  'user/email_active/regmessage.html')


def activate_user(request, token):
    '''激活用户'''

    try:
        '''
        校验用户的token（激活用户url）是否过期，过期抛出异常
        '''
        username = get_token_obj.confirm_validate_token(token)
    except:
        '''
        若用户token(激活用户url)过期，则删除数据中注册的用户信息，
        过期未激活，意味着注册失败
        '''
        try:
            username = get_token_obj.remove_validate_token(token)
            models.User.objects.filter(username= username,
                                       is_active= False).delete()
            log.info(f'{username}验证链接超时，注册失败')
        finally:
            return render(request, 'user/email_active/message.html',
                          {'message': "对不起，验证链接已经过期，请重新<a href='/user/register/'>注册</a>"})

    try:
        '''
        验证通过，则激活用户
        '''
        models.User.objects.filter(username= username, is_active= False
                                   ).update(is_active= True)
    except:
        return render(request, 'user/email_active/message.html',
                      {'message': "注册失败，请重新<a href='/user/register/'>注册</a>"})

    return render(request, 'user/email_active/message.html',
                  {'message': "用户已激活，请前往<a href='/user/login'>登录</a>"})


class LoginView(View):
    '''账号登录功能'''

    def get(self, request):
        return render(request, 'user/login.html')

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        host = request.get_host()
        back_dic = {'code': 1000, 'msg': ''}

        # 校验验证码
        if str(code).upper() == str(request.session['code']).upper():
            user_obj = self.validate_login_type(username)
            tag, username = self.validate_is_active(user_obj, host)

            # 判断用户是否已激活
            if tag:
                user_obj = auth.authenticate(request,
                                             username= username,
                                             password= password)
                # 校验用户、密码
                if user_obj:
                    # 通过，保存用户状态
                    auth.login(request, user_obj)
                    back_dic['url'] = '/home/'
                    log.info(f'{username}用户登录成功')
                else:
                    back_dic['code'] = 1001
                    back_dic['msg'] = '密码错误'

            else:
                back_dic['code'] = 1002
                back_dic['msg'] = username

        else:
            back_dic['code'] = 1003
            back_dic['msg'] = '验证码错误'

        return JsonResponse(back_dic)

    def validate_login_type(self, username):
        '''验证登录方式，账号/邮箱/手机'''
        if re.match('^1[3-9][0-9]{9}$', username):
            user_obj = models.User.objects.filter(
                telephone= username
            ).first()

        elif re.match('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-.]+\.[a-zA-Z0-9-.]',
                      username):
            user_obj = models.User.objects.filter(
                email= username
            ).first()

        else:
            user_obj = models.User.objects.filter(
                username= username
            ).first()

        return user_obj

    def validate_is_active(self, user_obj, host):
        '''
        验证用户是否激活
        '''
        try:

            if user_obj.is_active:
                return True, user_obj.username
            else:
                # 未激活，则发送激活邮件
                send_email.delay(user_obj.username,
                                 host,
                                 user_obj.email)
                return False,'用户未激活，请先激活用户,激活链接已发送至邮箱'

        except:
            return False,'用户不存在'


def get_code(request):
    '''获取图片验证码'''

    code_obj = AuthCode(size= (310, 32), font_size= 30)
    code, img_obj = code_obj.get_code()

    print(code)
    # 保存code到session
    request.session['code'] = code
    io_obj = BytesIO()  # 管理器对象
    img_obj.save(io_obj, 'png')   # 保存为png格式

    return HttpResponse(io_obj.getvalue())


class TelephoeLoginView(View):
    '''
    点击发送验证码
    输入验证码登录
    校验用户验证码
    校验用户手机号是否已注册用户
    '''
    def get(self, request):
        return render(request, 'user/phonelogin.html')


    def post(self,request):
        back_dic = {'code': 1000, 'msg': ''}
        telephone = request.POST.get('telephone')
        code = request.POST.get('code')

        if code == cache.get(settings.TELEPHONE_CACHE_KEY%telephone):

            if re.match('^1[3-9][0-9]{9}', telephone):
                user_obj = models.User.objects.filter(
                    telephone= telephone,
                    is_active= True
                ).first()

                if user_obj:
                    auth.login(request, user_obj)
                    back_dic['url'] = '/home/'
                    log.info(f'{telephone}手机用户登录成功')
                else:
                    back_dic['code'] = 1001
                    back_dic['msg'] = '该手机号码尚未注册'

            else:
                back_dic['code'] = 1002
                back_dic['msg'] = '手机号码无效'
        else:
            back_dic['code'] = 1003
            back_dic['msg'] = '验证码错误'

        return JsonResponse(back_dic)


class SendSmsCode(View):

    def get(self, request):
        '''
        校验手机号码格式
        发送验证码
        '''
        telephone = request.GET.get('telephone')
        code = send_sms.get_code()
        print(code)

        if re.match('^1[3-9][0-9]{9}$', telephone):
            result = send_sms.send_message(telephone, code)
            # 添加到缓存
            cache.set(settings.TELEPHONE_CACHE_KEY%telephone,
                      code , 300)

            if result:
                return HttpResponse('验证码已发送')
            else:
                return HttpResponse('验证码发送失败')

        else:
            return HttpResponse('手机号码无效')


def logout(request):
    auth.logout(request)
    return redirect('/home/')


@login_required
def set_password(request):
    '''修改密码'''

    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        confirm_password = request.POST.get('confirm_password')
        back_dic = {'code': 1000, 'msg': ''}

        # 判断原密码
        is_right = request.user.check_password(old_password)
        if is_right:

            if new_password == confirm_password:
                # 修改密码并保存
                request.user.set_password(new_password)
                request.user.save()
                log.info(f'{request.user}用户修改密码')
                back_dic['msg'] = '修改密码成功'
            else:
                back_dic['code'] = 1001
                back_dic['msg'] = '两次密码输入不一致'

        else:
            back_dic['code'] = 1002
            back_dic['msg'] = '原密码错误'

    return JsonResponse(back_dic)







